
/**
 * Date:2019年5月30日下午4:39:10
 * Copyright (c) 2019, www.bwbroad.com All Rights Reserved.
 *
*/

package com.xue.im.server.core;

import java.net.InetSocketAddress;

import com.xue.im.common.IMUtil;
import com.xue.im.common.coder.MessageDecoder;
import com.xue.im.common.coder.MessageEncoder;
import com.xue.im.server.handler.HeartBeatResponseHandler;
import com.xue.im.server.handler.LoginAuthResponseHandler;
import com.xue.im.server.handler.TextResponseHandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;

/**
 * Description: 服务端 <br/>
 * Date: 2019年5月30日 下午4:39:10 <br/>
 * 
 * @author xuejianxin
 */
public class IMServer {
	private final int port;

	public IMServer(int port) {
		this.port = port;
	}

	public void start() throws Exception {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup wokerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, wokerGroup).option(ChannelOption.SO_BACKLOG, 100)
					// .handler(new LoggingHandler(LogLevel.INFO))
					.channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch) throws Exception {
							ch.pipeline().addLast("decoder", new MessageDecoder(IMUtil.MESSAGE_LEN, 4, 4));
							ch.pipeline().addLast("encoder", new MessageEncoder());
							ch.pipeline().addLast("readTimeout", new ReadTimeoutHandler(50));
							ch.pipeline().addLast("login", new LoginAuthResponseHandler());
							ch.pipeline().addLast("heartBeat", new HeartBeatResponseHandler());
							ch.pipeline().addLast("text", new TextResponseHandler());
						}
					});
			b.childOption(ChannelOption.SO_KEEPALIVE, true);// 保持长连接
			ChannelFuture f = b.bind().sync();
			f.addListener(new ChannelFutureListener() {
				public void operationComplete(ChannelFuture cf) throws Exception {
					if (f.isSuccess()) {
						System.out.println("server start success!");
					} else {
						System.err.println("server start fail !!!!");
						f.cause().printStackTrace();
					}
				}
			});

			f.channel().closeFuture().sync();

		} finally {
			wokerGroup.shutdownGracefully().sync();
			bossGroup.shutdownGracefully().sync();
		}
	}

}